using System.Linq;
using System.Collections;
using System.Linq.Expressions;

namespace YogaStudio.Data.Migrations
{
    using System.Data.Entity.Migrations;
    using Domain;
    using System.Collections.Generic;
    using System;

    internal sealed class Configuration : DbMigrationsConfiguration<YogaStudioEntities>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = true;
            AutomaticMigrationDataLossAllowed = true;
        }

        protected override void Seed(YogaStudioEntities context)
        {
            if (context.Roles.Any())
            {
                return;
            }
            AddUserAndRoles(context);
            AddFacultiesAndCustomersWithUser(context);
            AddCourse(context);
            AddWaivers(context);
            AddShippingStatus(context);
            AddRoom(context);
            AddSemesterAndSchedule(context);
            AddSection(context);
            AddEnrollment(context);
        }

        private void AddShippingStatus(YogaStudioEntities context)
        {
            context.ShippingStatus.Add(new ShippingStatus{ ShippingStatusName = "InOrder"});
            context.ShippingStatus.Add(new ShippingStatus { ShippingStatusName = "Shipped" });
            context.ShippingStatus.Add(new ShippingStatus { ShippingStatusName = "Delivered" });
            context.SaveChanges();
        }

        void AddUserAndRoles(YogaStudioEntities context)
        {
            context.Roles.AddOrUpdate( new Role { RoleName = "Admin", RoleDescription = "Admin User" });
            context.Roles.AddOrUpdate(new Role { RoleName = "Faculty", RoleDescription = "Faculty User" });
            context.Roles.AddOrUpdate(new Role { RoleName = "Customer", RoleDescription = "Customer User" });
            context.SaveChanges();
        }

        void AddFacultiesAndCustomersWithUser(YogaStudioEntities context)
        {
            new[] {
                new User
                {
                    UserName = "TB",
                    Password = "25f9e794323b453885f5181f1b624d0b",
                    UserEmailAddress = "tb@gmail.com",
                    isConfirmed = true,
                },
                new User
                {
                    UserName = "THB",
                    Password = "25f9e794323b453885f5181f1b624d0b",
                    UserEmailAddress = "thb@gmail.com",
                    isConfirmed = true,
                },
                new User
                {
                    UserName = "David",
                    Password = "25f9e794323b453885f5181f1b624d0b",
                    UserEmailAddress = "david@gmail.com",
                    isConfirmed = true,
                },
                new User
                {
                    UserName = "Anup",
                    Password = "25f9e794323b453885f5181f1b624d0b",
                    UserEmailAddress = "anup@gmail.com",
                    isConfirmed = true,
                },
                new User
                {
                    UserName = "Yasmin",
                    Password = "25f9e794323b453885f5181f1b624d0b",
                    UserEmailAddress = "yasmin@gmail.com",
                    isConfirmed = true,
                },
                new User
                {
                    UserName = "Berihu",
                    Password = "25f9e794323b453885f5181f1b624d0b",
                    UserEmailAddress = "berihu@gmail.com",
                    isConfirmed = true,
                },
                new User
                {
                    UserName = "Bikal",
                    Password = "25f9e794323b453885f5181f1b624d0b",
                    UserEmailAddress = "bikal@gmail.com",
                    isConfirmed = true,
                },
                new User
                {
                    UserName = "FT",
                    Password = "25f9e794323b453885f5181f1b624d0b",
                    UserEmailAddress = "ft@gmail.com",
                    isConfirmed = true,
                },
                new User
                {
                    UserName = "Ruby",
                    Password = "25f9e794323b453885f5181f1b624d0b",
                    UserEmailAddress = "ruby@gmail.com",
                    isConfirmed = true,
                },
                new User
                {
                    UserName = "Admin",
                    Password = "25f9e794323b453885f5181f1b624d0b",
                    UserEmailAddress = "admin@gmail.com",
                    isConfirmed = true,
                }
            }.ToList().ForEach(u => context.Users.AddOrUpdate(u));
            context.SaveChanges();

            new[] {
                new UserRole
                {
                    Role = context.Roles.Single(r => r.RoleName == "Customer"),
                    User = context.Users.Single(u => u.UserName == "TB")
                },
                new UserRole
                {
                    Role = context.Roles.Single(r => r.RoleName == "Customer"),
                    User = context.Users.Single(u => u.UserName == "THB")
                },
                new UserRole
                {
                    Role = context.Roles.Single(r => r.RoleName == "Customer"),
                    User = context.Users.Single(u => u.UserName == "David")
                },
                new UserRole
                {
                    Role = context.Roles.Single(r => r.RoleName == "Customer"),
                    User = context.Users.Single(u => u.UserName == "Anup")
                },
                new UserRole
                {
                    Role = context.Roles.Single(r => r.RoleName == "Customer"),
                    User = context.Users.Single(u => u.UserName == "Yasmin")
                },
                new UserRole
                {
                    Role = context.Roles.Single(r => r.RoleName == "Customer"),
                    User = context.Users.Single(u => u.UserName == "Berihu")
                },
                new UserRole
                {
                    Role = context.Roles.Single(r => r.RoleName == "Customer"),
                    User = context.Users.Single(u => u.UserName == "Bikal")
                },
                new UserRole
                {
                    Role = context.Roles.Single(r => r.RoleName == "Faculty"),
                    User = context.Users.Single(u => u.UserName == "FT")
                },
                new UserRole
                {
                    Role = context.Roles.Single(r => r.RoleName == "Faculty"),
                    User = context.Users.Single(u => u.UserName == "Ruby")
                },
                new UserRole
                {
                    Role = context.Roles.Single(r => r.RoleName == "Admin"),
                    User = context.Users.Single(u => u.UserName == "Admin")
                }
            }.ToList().ForEach(r => context.UserRoles.AddOrUpdate(r));
            context.SaveChanges();

            new[] {
                new Faculty
                {
                    User = context.Users.Single(u => u.UserName == "FT"),
                    FullName = "Steve Nolle",
                    Address = "FF, IA",
                    PhoneNumber = "(515) 81979",
                    Email = "steve@gmail.com",
                    Title = "phD"
                },
                new Faculty
                {
                    User = context.Users.Single(u => u.UserName == "Ruby"),
                    FullName = "Ruby",
                    Address = "FF, IA",
                    PhoneNumber = "(515) 2637",
                    Email = "ruby@gmail.com",
                    Title = "phD"
                }
            }.ToList().ForEach(f => context.Faculties.AddOrUpdate(f));
            context.SaveChanges();

            new[] {
                new Customer
                {
                    User = context.Users.Single(u => u.UserName == "TB"),
                    FullName = "Tan Bui",
                    Address = "FF, IA",
                    PhoneNumber = "(515) 779",
                    Advisor = context.Faculties.Single(f => f.User.UserName == "FT")
                },
                new Customer
                {
                    User = context.Users.Single(u => u.UserName == "THB"),
                    FullName = "Tan H Bui",
                    Address = "FF, IA",
                    PhoneNumber = "(515) 744",
                    Advisor = context.Faculties.Single(f => f.User.UserName == "FT")
                },
                new Customer
                {
                    User = context.Users.Single(u => u.UserName == "David"),
                    FullName = "David Beckham",
                    Address = "UK",
                    PhoneNumber = "(123) 456 789",
                    Advisor = context.Faculties.Single(f => f.User.UserName == "FT")
                },
                new Customer
                {
                    User = context.Users.Single(u => u.UserName == "Anup"),
                    FullName = "Anup Paudel",
                    Address = "FF, IA",
                    PhoneNumber = "(515) 44610",
                    Advisor = context.Faculties.Single(f => f.User.UserName == "Ruby")
                },
                new Customer
                {
                    User = context.Users.Single(u => u.UserName == "Yasmin"),
                    FullName = "Yasmin Tamim",
                    Address = "FF, IA",
                    PhoneNumber = "(515) 7451 314",
                    Advisor = context.Faculties.Single(f => f.User.UserName == "Ruby")
                },
                new Customer
                {
                    User = context.Users.Single(u => u.UserName == "Berihu"),
                    FullName = "Berihu Zeru",
                    Address = "FF, IA",
                    PhoneNumber = "(515) 397169",
                    Advisor = context.Faculties.Single(f => f.User.UserName == "Ruby")
                },
                new Customer
                {
                    User = context.Users.Single(u => u.UserName == "Bikal"),
                    FullName = "Bikal Bhattarai",
                    Address = "FF, IA",
                    PhoneNumber = "(515) 31741",
                    Advisor = context.Faculties.Single(f => f.User.UserName == "Ruby")
                }
            }.ToList().ForEach(c => context.Customers.AddOrUpdate(c));
            context.SaveChanges();
        }

        public void AddCourse(YogaStudioEntities context)
        {
            new[] {
                new Course{
                    CourseCode = "101",
                    CourseName = "TM",
                    CourseDescription = "Transcendental Meditation"
                },
                new Course{
                    CourseCode = "102",
                    CourseName = "Yoga 1",
                    CourseDescription = "Basic Yoga",
                    //Prerequisite = context.Courses.Single(c => c.CourseCode == "101")
                },
                new Course{
                    CourseCode = "202",
                    CourseName = "Yoga 2",
                    CourseDescription = "Yoga for beginners",
                    //Prerequisite = context.Courses.Single(c => c.CourseCode == "101")
                },
                new Course{
                    CourseCode = "CS425",
                    CourseName = "SE",
                    CourseDescription = "Software Engineering"
                },
                new Course{
                    CourseCode = "CS525",
                    CourseName = "ASD",
                    CourseDescription = "Advance Software Development"
                }
            }.ToList().ForEach(c => context.Courses.AddOrUpdate(c));
            context.SaveChanges();

            var yoga1 = context.Courses.Single(c => c.CourseCode == "102");
            yoga1.Prerequisite = context.Courses.Single(c => c.CourseCode == "101");
            context.SaveChanges();
        }

        public void AddWaivers(YogaStudioEntities context)
        {
            new[] {
                new WaiverRequest {
                    Customer = context.Customers.Single(c => c.User.UserName == "TB"),
                    Course = context.Courses.Single(c => c.CourseName == "ASD"),
                    Faculty = context.Faculties.Single(c => c.User.UserName == "FT"),
                    Status = WaiverRequestStatus.Open,
                    Reason = "I don't want to study this. I've already had experience."
                },
                new WaiverRequest {
                    Customer = context.Customers.Single(c => c.User.UserName == "THB"),
                    Course = context.Courses.Single(c => c.CourseName == "SE"),
                    Faculty = context.Faculties.Single(c => c.User.UserName == "FT"),
                    Status = WaiverRequestStatus.Open,
                    Reason = "I don't want to study this. I've already had experience."
                }
            }.ToList().ForEach(w => context.WaiverRequests.AddOrUpdate(w));
            context.SaveChanges();
        }

        public void AddSemesterAndSchedule(YogaStudioEntities context)
        {
            new[] {
                new Semester {
                    SemesterName = "Spring"
                },
                new Semester {
                    SemesterName = "Summer"
                },
                new Semester {
                    SemesterName = "Fall"
                },
            }.ToList().ForEach(s => context.Semesters.Add(s));
            context.SaveChanges();

            new[] {
                new Schedule {
                    Year = 2014,
                    Semester = context.Semesters.Single(s => s.SemesterName == "Spring"),
                    FromDate = new DateTime(2014, 2, 1),
                    ToDate = new DateTime(2014, 5, 31)
                },
                new Schedule {
                    Year = 2014,
                    Semester = context.Semesters.Single(s => s.SemesterName == "Summer"),
                    FromDate = new DateTime(2014, 6, 1),
                    ToDate = new DateTime(2014, 9, 30)
                },
                new Schedule {
                    Year = 2014,
                    Semester = context.Semesters.Single(s => s.SemesterName == "Fall"),
                    FromDate = new DateTime(2014, 10, 1),
                    ToDate = new DateTime(2015, 1, 31)
                },
                new Schedule {
                    Year = 2015,
                    Semester = context.Semesters.Single(s => s.SemesterName == "Spring"),
                    FromDate = new DateTime(2015, 2, 1),
                    ToDate = new DateTime(2015, 5, 31)
                }
            }.ToList().ForEach(s => context.Schedules.Add(s));
            context.SaveChanges();
        }

        public void AddRoom(YogaStudioEntities context)
        {
            new[] {
                new Room {
                    RoomNo = "105"
                },
                new Room {
                    RoomNo = "115"
                }
            }.ToList().ForEach(r => context.Rooms.Add(r));
            context.SaveChanges();
        }

        public void AddSection(YogaStudioEntities context)
        {
            new[] {
                new Section {
                    Course = context.Courses.Single(c => c.CourseName == "TM"),
                    Faculty = context.Faculties.Single(f => f.User.UserName == "FT"),
                    Schedule = context.Schedules.Single(s => s.FromDate == new DateTime(2014, 2, 1)),
                    Room = context.Rooms.Single(r => r.RoomNo == "105"),
                    Price = 1000,
                    Capacity = 10,
                    Customers = new List<Customer>()
                },
                new Section {
                    Course = context.Courses.Single(c => c.CourseName == "Yoga 1"),
                    Faculty = context.Faculties.Single(f => f.User.UserName == "FT"),
                    Schedule = context.Schedules.Single(s => s.FromDate == new DateTime(2014, 6, 1)),
                    Room = context.Rooms.Single(r => r.RoomNo == "105"),
                    Price = 1000,
                    Capacity = 10,
                    Customers = new List<Customer>()
                },
                new Section {
                    Course = context.Courses.Single(c => c.CourseName == "SE"),
                    Faculty = context.Faculties.Single(f => f.User.UserName == "FT"),
                    Schedule = context.Schedules.Single(s => s.FromDate == new DateTime(2014, 10, 1)),
                    Room = context.Rooms.Single(r => r.RoomNo == "105"),
                    Price = 1000,
                    Capacity = 10,
                    Customers = new List<Customer>()
                },
                new Section {
                    Course = context.Courses.Single(c => c.CourseName == "ASD"),
                    Faculty = context.Faculties.Single(f => f.User.UserName == "Ruby"),
                    Schedule = context.Schedules.Single(s => s.FromDate == new DateTime(2014, 10, 1)),
                    Room = context.Rooms.Single(r => r.RoomNo == "115"),
                    Price = 1000,
                    Capacity = 10,
                    Customers = new List<Customer>()
                },
                new Section {
                    Course = context.Courses.Single(c => c.CourseName == "Yoga 2"),
                    Faculty = context.Faculties.Single(f => f.User.UserName == "FT"),
                    Schedule = context.Schedules.Single(s => s.FromDate == new DateTime(2015, 2, 1)),
                    Room = context.Rooms.Single(r => r.RoomNo == "105"),
                    Price = 1000,
                    Capacity = 10,
                    Customers = new List<Customer>()
                },
            }.ToList().ForEach(s => context.Sections.Add(s));
            context.SaveChanges();
        }

        public void AddEnrollment(YogaStudioEntities context)
        {
            context.Sections
                .Single(s => s.Course.CourseName == "SE" && s.Schedule.FromDate == new DateTime(2014, 10, 1))
                .Customers.Add(context.Customers.Single(c => c.User.UserName == "TB"));
            context.Sections
                .Single(s => s.Course.CourseName == "SE" && s.Schedule.FromDate == new DateTime(2014, 10, 1))
                .Customers.Add(context.Customers.Single(c => c.User.UserName == "David"));
            context.Sections
                .Single(s => s.Course.CourseName == "ASD" && s.Schedule.FromDate == new DateTime(2014, 10, 1))
                .Customers.Add(context.Customers.Single(c => c.User.UserName == "THB"));
            context.Sections
                .Single(s => s.Course.CourseName == "Yoga 2" && s.Schedule.FromDate == new DateTime(2015, 2, 1))
                .Customers.Add(context.Customers.Single(c => c.User.UserName == "Anup"));
            context.Sections
                .Single(s => s.Course.CourseName == "Yoga 2" && s.Schedule.FromDate == new DateTime(2015, 2, 1))
                .Customers.Add(context.Customers.Single(c => c.User.UserName == "Yasmin"));
            context.Sections
                .Single(s => s.Course.CourseName == "Yoga 2" && s.Schedule.FromDate == new DateTime(2015, 2, 1))
                .Customers.Add(context.Customers.Single(c => c.User.UserName == "Berihu"));
            context.Sections
                .Single(s => s.Course.CourseName == "Yoga 2" && s.Schedule.FromDate == new DateTime(2015, 2, 1))
                .Customers.Add(context.Customers.Single(c => c.User.UserName == "Bikal"));
            context.SaveChanges();
        }
    }
}
